<?php
/**
 * 小程序公告API
 * 提供公告列表、详情、点赞等功能
 */

header('Content-Type: application/json; charset=utf-8');
header('Access-Control-Allow-Origin: *');
header('Access-Control-Allow-Methods: GET, POST, PUT, DELETE, OPTIONS');
header('Access-Control-Allow-Headers: Content-Type, Authorization');

if ($_SERVER['REQUEST_METHOD'] == 'OPTIONS') {
    exit;
}

// 数据库配置
$dbConfig = [
    'host' => 'localhost',
    'name' => 'nzy_congqian_cn', 
    'user' => 'nzy_congqian_cn',
    'pass' => 'FsnXrDfDhm4wFJSX',
    'charset' => 'utf8mb4'
];

// 数据库连接
try {
    $dsn = "mysql:host={$dbConfig['host']};dbname={$dbConfig['name']};charset={$dbConfig['charset']}";
    $pdo = new PDO($dsn, $dbConfig['user'], $dbConfig['pass']);
    $pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
} catch (PDOException $e) {
    jsonResponse([
        'success' => false,
        'message' => '数据库连接失败: ' . $e->getMessage()
    ]);
}

// 响应函数
function jsonResponse($data) {
    echo json_encode($data, JSON_UNESCAPED_UNICODE);
    exit;
}

function success($data = null, $message = '操作成功') {
    jsonResponse([
        'code' => 200,
        'success' => true,
        'message' => $message,
        'data' => $data,
        'timestamp' => time()
    ]);
}

function error($message = '操作失败', $code = 400) {
    jsonResponse([
        'code' => $code,
        'success' => false,
        'message' => $message,
        'data' => null,
        'timestamp' => time()
    ]);
}

// 验证微信用户token（可选）
function verifyWxToken($token) {
    global $pdo;
    
    if (empty($token)) {
        return null;
    }
    
    try {
        $sql = "SELECT * FROM users WHERE (openid = ? OR token = ?) AND token_expires > NOW() AND status = 'active'";
        $stmt = $pdo->prepare($sql);
        $stmt->execute([$token, $token]);
        $user = $stmt->fetch(PDO::FETCH_ASSOC);
        
        return $user;
    } catch (Exception $e) {
        return null;
    }
}

// 获取用户token（可选）
function getUserToken() {
    $headers = getallheaders();
    $authHeader = $headers['Authorization'] ?? $headers['authorization'] ?? '';
    
    if (strpos($authHeader, 'Bearer ') === 0) {
        return substr($authHeader, 7);
    }
    
    return $_GET['token'] ?? $_POST['token'] ?? $_GET['openid'] ?? $_POST['openid'] ?? '';
}

// 获取当前用户（可选，用于点赞等需要登录的功能）
function getCurrentUser() {
    $token = getUserToken();
    if (!$token) {
        return null;
    }
    return verifyWxToken($token);
}

// 记录公告查看
function recordAnnouncementView($announcementId, $userId = null) {
    global $pdo;
    
    try {
        $ip = $_SERVER['HTTP_X_FORWARDED_FOR'] ?? $_SERVER['REMOTE_ADDR'] ?? '';
        $userAgent = $_SERVER['HTTP_USER_AGENT'] ?? '';
        $source = 'miniapp';
        
        // 检查是否已经记录过（防止重复统计）
        $checkSql = "SELECT id FROM announcement_views 
                     WHERE announcement_id = ? AND ip_address = ? 
                     AND view_time > DATE_SUB(NOW(), INTERVAL 1 HOUR)";
        $checkStmt = $pdo->prepare($checkSql);
        $checkStmt->execute([$announcementId, $ip]);
        
        if (!$checkStmt->fetch()) {
            // 记录新的查看
            $insertSql = "INSERT INTO announcement_views 
                         (announcement_id, user_id, ip_address, user_agent, device_type, source) 
                         VALUES (?, ?, ?, ?, 'mobile', ?)";
            $insertStmt = $pdo->prepare($insertSql);
            $insertStmt->execute([$announcementId, $userId, $ip, $userAgent, $source]);
            
            // 更新公告查看计数
            $updateSql = "UPDATE announcements SET view_count = view_count + 1 WHERE id = ?";
            $updateStmt = $pdo->prepare($updateSql);
            $updateStmt->execute([$announcementId]);
        }
    } catch (Exception $e) {
        // 记录查看失败不影响主要功能
        error_log('记录公告查看失败: ' . $e->getMessage());
    }
}

// 获取公告列表
function getAnnouncementList() {
    global $pdo;
    
    try {
        $page = max(1, intval($_GET['page'] ?? 1));
        $limit = min(50, max(5, intval($_GET['limit'] ?? 10)));
        $offset = ($page - 1) * $limit;
        
        // 构建查询条件
        $where = "WHERE a.is_published = 1 AND (a.expire_time IS NULL OR a.expire_time > NOW())";
        $params = [];
        
        // 分类筛选
        if (!empty($_GET['category'])) {
            $where .= " AND a.category = ?";
            $params[] = $_GET['category'];
        }
        
        // 目标受众筛选
        if (!empty($_GET['target_audience'])) {
            $where .= " AND (a.target_audience = 'all' OR a.target_audience = ?)";
            $params[] = $_GET['target_audience'];
        }
        
        // 关键词搜索
        if (!empty($_GET['keyword'])) {
            $keyword = '%' . $_GET['keyword'] . '%';
            $where .= " AND (a.title LIKE ? OR a.summary LIKE ? OR a.tags LIKE ?)";
            $params = array_merge($params, [$keyword, $keyword, $keyword]);
        }
        
        // 获取总数
        $countSql = "SELECT COUNT(*) FROM announcements a $where";
        $countStmt = $pdo->prepare($countSql);
        $countStmt->execute($params);
        $total = $countStmt->fetchColumn();
        
        // 获取数据
        $sql = "SELECT 
                    a.id,
                    a.title,
                    a.subtitle,
                    a.summary,
                    a.cover_image,
                    a.category,
                    a.priority,
                    a.is_pinned,
                    a.is_featured,
                    a.publish_time,
                    a.view_count,
                    a.like_count,
                    a.tags,
                    a.target_audience,
                    a.created_at,
                    ac.name as category_name,
                    ac.color as category_color,
                    ac.icon as category_icon
                FROM announcements a 
                LEFT JOIN announcement_categories ac ON a.category = ac.slug
                $where 
                ORDER BY a.is_pinned DESC, a.priority DESC, a.sort_order DESC, a.publish_time DESC 
                LIMIT $limit OFFSET $offset";
        
        $stmt = $pdo->prepare($sql);
        $stmt->execute($params);
        $announcements = $stmt->fetchAll(PDO::FETCH_ASSOC);
        
        // 格式化数据
        foreach ($announcements as &$announcement) {
            $announcement['id'] = intval($announcement['id']);
            $announcement['priority'] = intval($announcement['priority']);
            $announcement['is_pinned'] = intval($announcement['is_pinned']) === 1;
            $announcement['is_featured'] = intval($announcement['is_featured']) === 1;
            $announcement['view_count'] = intval($announcement['view_count']);
            $announcement['like_count'] = intval($announcement['like_count']);
            $announcement['tags'] = $announcement['tags'] ? explode(',', $announcement['tags']) : [];
            
            // 生成摘要（如果没有设置）
            if (empty($announcement['summary'])) {
                $announcement['summary'] = mb_substr(strip_tags($announcement['content'] ?? ''), 0, 100) . '...';
            }
            
            // 格式化时间
            $announcement['publish_time'] = $announcement['publish_time'];
            $announcement['created_at'] = $announcement['created_at'];
            
            // 添加相对时间
            $announcement['time_ago'] = getTimeAgo($announcement['publish_time'] ?? $announcement['created_at']);
        }
        
        success([
            'list' => $announcements,
            'pagination' => [
                'page' => $page,
                'limit' => $limit,
                'total' => intval($total),
                'pages' => ceil($total / $limit)
            ]
        ]);
        
    } catch (Exception $e) {
        error('获取公告列表失败: ' . $e->getMessage(), 500);
    }
}

// 获取公告详情
function getAnnouncementDetail() {
    global $pdo;
    
    $id = $_GET['id'] ?? 0;
    if (!$id) {
        error('缺少公告ID');
    }
    
    try {
        $sql = "SELECT 
                    a.*,
                    ac.name as category_name,
                    ac.color as category_color,
                    ac.icon as category_icon
                FROM announcements a 
                LEFT JOIN announcement_categories ac ON a.category = ac.slug
                WHERE a.id = ? AND a.is_published = 1";
        
        $stmt = $pdo->prepare($sql);
        $stmt->execute([$id]);
        $announcement = $stmt->fetch(PDO::FETCH_ASSOC);
        
        if (!$announcement) {
            error('公告不存在或已下线', 404);
        }
        
        // 检查是否过期
        if ($announcement['expire_time'] && strtotime($announcement['expire_time']) < time()) {
            error('公告已过期', 404);
        }
        
        // 记录查看
        $user = getCurrentUser();
        recordAnnouncementView($id, $user['id'] ?? null);
        
        // 格式化数据
        $announcement['id'] = intval($announcement['id']);
        $announcement['priority'] = intval($announcement['priority']);
        $announcement['is_pinned'] = intval($announcement['is_pinned']) === 1;
        $announcement['is_featured'] = intval($announcement['is_featured']) === 1;
        $announcement['view_count'] = intval($announcement['view_count']) + 1; // 实时更新
        $announcement['like_count'] = intval($announcement['like_count']);
        $announcement['images'] = $announcement['images'] ? json_decode($announcement['images'], true) : [];
        $announcement['tags'] = $announcement['tags'] ? explode(',', $announcement['tags']) : [];
        
        // 添加相对时间
        $announcement['time_ago'] = getTimeAgo($announcement['publish_time'] ?? $announcement['created_at']);
        
        // 检查用户是否已点赞
        $announcement['is_liked'] = false;
        if ($user) {
            $likeSql = "SELECT id FROM announcement_likes WHERE announcement_id = ? AND user_id = ?";
            $likeStmt = $pdo->prepare($likeSql);
            $likeStmt->execute([$id, $user['id']]);
            $announcement['is_liked'] = $likeStmt->fetch() ? true : false;
        }
        
        // 获取相关公告（同分类的其他公告）
        $relatedSql = "SELECT id, title, cover_image, view_count, publish_time 
                       FROM announcements 
                       WHERE category = ? AND id != ? AND is_published = 1 
                       AND (expire_time IS NULL OR expire_time > NOW())
                       ORDER BY view_count DESC, publish_time DESC 
                       LIMIT 5";
        $relatedStmt = $pdo->prepare($relatedSql);
        $relatedStmt->execute([$announcement['category'], $id]);
        $relatedAnnouncements = $relatedStmt->fetchAll(PDO::FETCH_ASSOC);
        
        $announcement['related_announcements'] = $relatedAnnouncements;
        
        success($announcement);
        
    } catch (Exception $e) {
        error('获取公告详情失败: ' . $e->getMessage(), 500);
    }
}

// 点赞/取消点赞公告
function likeAnnouncement() {
    global $pdo;
    
    $user = getCurrentUser();
    if (!$user) {
        error('请先登录', 401);
    }
    
    $input = json_decode(file_get_contents('php://input'), true);
    $id = $input['id'] ?? 0;
    if (!$id) {
        error('缺少公告ID');
    }
    
    try {
        $pdo->beginTransaction();
        
        // 检查公告是否存在
        $checkSql = "SELECT id FROM announcements WHERE id = ? AND is_published = 1";
        $checkStmt = $pdo->prepare($checkSql);
        $checkStmt->execute([$id]);
        if (!$checkStmt->fetch()) {
            error('公告不存在', 404);
        }
        
        // 检查是否已点赞
        $likeSql = "SELECT id FROM announcement_likes WHERE announcement_id = ? AND user_id = ?";
        $likeStmt = $pdo->prepare($likeSql);
        $likeStmt->execute([$id, $user['id']]);
        $existingLike = $likeStmt->fetch();
        
        if ($existingLike) {
            // 取消点赞
            $deleteSql = "DELETE FROM announcement_likes WHERE id = ?";
            $deleteStmt = $pdo->prepare($deleteSql);
            $deleteStmt->execute([$existingLike['id']]);
            
            $updateSql = "UPDATE announcements SET like_count = like_count - 1 WHERE id = ?";
            $updateStmt = $pdo->prepare($updateSql);
            $updateStmt->execute([$id]);
            
            $isLiked = false;
            $message = '已取消点赞';
        } else {
            // 添加点赞
            $insertSql = "INSERT INTO announcement_likes (announcement_id, user_id, ip_address) VALUES (?, ?, ?)";
            $insertStmt = $pdo->prepare($insertSql);
            $insertStmt->execute([$id, $user['id'], $_SERVER['REMOTE_ADDR'] ?? '']);
            
            $updateSql = "UPDATE announcements SET like_count = like_count + 1 WHERE id = ?";
            $updateStmt = $pdo->prepare($updateSql);
            $updateStmt->execute([$id]);
            
            $isLiked = true;
            $message = '点赞成功';
        }
        
        // 获取最新点赞数
        $countSql = "SELECT like_count FROM announcements WHERE id = ?";
        $countStmt = $pdo->prepare($countSql);
        $countStmt->execute([$id]);
        $likeCount = $countStmt->fetchColumn();
        
        $pdo->commit();
        
        success([
            'is_liked' => $isLiked,
            'like_count' => intval($likeCount)
        ], $message);
        
    } catch (Exception $e) {
        $pdo->rollBack();
        error('操作失败: ' . $e->getMessage(), 500);
    }
}

// 获取公告分类
function getAnnouncementCategories() {
    global $pdo;
    
    try {
        $sql = "SELECT 
                    ac.*,
                    COUNT(a.id) as announcement_count
                FROM announcement_categories ac
                LEFT JOIN announcements a ON ac.slug = a.category 
                    AND a.is_published = 1 
                    AND (a.expire_time IS NULL OR a.expire_time > NOW())
                WHERE ac.is_active = 1 
                GROUP BY ac.id
                ORDER BY ac.sort_order ASC";
        
        $stmt = $pdo->query($sql);
        $categories = $stmt->fetchAll(PDO::FETCH_ASSOC);
        
        foreach ($categories as &$category) {
            $category['announcement_count'] = intval($category['announcement_count']);
            $category['is_active'] = intval($category['is_active']) === 1;
        }
        
        success($categories);
        
    } catch (Exception $e) {
        error('获取分类失败: ' . $e->getMessage(), 500);
    }
}

// 获取热门公告
function getPopularAnnouncements() {
    global $pdo;
    
    try {
        $limit = min(20, max(5, intval($_GET['limit'] ?? 10)));
        $days = min(30, max(1, intval($_GET['days'] ?? 7))); // 默认7天内的热门
        
        $sql = "SELECT 
                    a.id,
                    a.title,
                    a.subtitle,
                    a.summary,
                    a.cover_image,
                    a.category,
                    a.view_count,
                    a.like_count,
                    a.publish_time,
                    ac.name as category_name,
                    ac.color as category_color
                FROM announcements a 
                LEFT JOIN announcement_categories ac ON a.category = ac.slug
                WHERE a.is_published = 1 
                    AND (a.expire_time IS NULL OR a.expire_time > NOW())
                    AND a.publish_time >= DATE_SUB(NOW(), INTERVAL ? DAY)
                ORDER BY (a.view_count * 0.7 + a.like_count * 0.3) DESC
                LIMIT $limit";
        
        $stmt = $pdo->prepare($sql);
        $stmt->execute([$days]);
        $announcements = $stmt->fetchAll(PDO::FETCH_ASSOC);
        
        foreach ($announcements as &$announcement) {
            $announcement['id'] = intval($announcement['id']);
            $announcement['view_count'] = intval($announcement['view_count']);
            $announcement['like_count'] = intval($announcement['like_count']);
            $announcement['time_ago'] = getTimeAgo($announcement['publish_time']);
        }
        
        success($announcements);
        
    } catch (Exception $e) {
        error('获取热门公告失败: ' . $e->getMessage(), 500);
    }
}

// 获取相对时间
function getTimeAgo($datetime) {
    $time = time() - strtotime($datetime);
    
    if ($time < 60) {
        return '刚刚';
    } elseif ($time < 3600) {
        return floor($time / 60) . '分钟前';
    } elseif ($time < 86400) {
        return floor($time / 3600) . '小时前';
    } elseif ($time < 2592000) {
        return floor($time / 86400) . '天前';
    } else {
        return date('Y-m-d', strtotime($datetime));
    }
}

// 处理请求
$method = $_SERVER['REQUEST_METHOD'];
$action = $_GET['action'] ?? '';

try {
    switch ($method) {
        case 'GET':
            switch ($action) {
                case 'list':
                    getAnnouncementList();
                    break;
                case 'detail':
                    getAnnouncementDetail();
                    break;
                case 'categories':
                    getAnnouncementCategories();
                    break;
                case 'popular':
                    getPopularAnnouncements();
                    break;
                default:
                    error('无效的操作');
            }
            break;
            
        case 'POST':
            switch ($action) {
                case 'like':
                    likeAnnouncement();
                    break;
                default:
                    error('无效的操作');
            }
            break;
            
        default:
            error('不支持的请求方法');
    }
    
} catch (PDOException $e) {
    error('数据库错误: ' . $e->getMessage(), 500);
} catch (Exception $e) {
    error('服务器错误: ' . $e->getMessage(), 500);
}
?>